#pragma once

#include "C_SQLite.h"

typedef const char* char_array;

class C_SQLiteQuery
{
protected:
	std::string		m_strQuery;
	C_SQLite		*m_sql;
	std::string		m_tname;
public:
	C_SQLiteQuery(C_SQLite *sql);
	virtual ~C_SQLiteQuery();

	inline char_array query() { return m_strQuery.c_str(); }
	inline virtual std::string execToStr() { return ""; }
	inline std::string tableName() { return m_tname; }
};


////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//			C_SQLiteTable
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
class C_SQLiteTable : public C_SQLiteQuery
{
private:
	std::vector<std::string> m_columns;
public:
	C_SQLiteTable(C_SQLite *sql) : C_SQLiteQuery(sql) {}
	virtual ~C_SQLiteTable() {}

	inline void setName(std::string name)	{ m_tname = name; }
	inline void add(std::string name)		{ m_columns.push_back(name); }
	inline void exec() {
		m_strQuery = "CREATE TABLE " + m_tname + " (";
		FOR_VEC_I(it, m_columns, std::string)
		{
			m_strQuery += (*it) + ((it + 1 != m_columns.end()) ? ", " : ");");
		}
		//execution
		m_sql->exec(m_strQuery);
	}
	inline virtual std::string execToStr()
	{
		m_strQuery = "CREATE TABLE " + m_tname + " (";
		FOR_VEC_I(it, m_columns, std::string)
		{
			m_strQuery += (*it) + ((it + 1 != m_columns.end()) ? ", " : ");");
		}
		return m_strQuery;
	}
};

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//			C_SQLiteInsert
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
class C_SQLiteInsert : public C_SQLiteQuery
{
private:
	std::vector<std::string> m_columns;
	std::vector<std::string> m_values;
public:
	C_SQLiteInsert(C_SQLite *sql) : C_SQLiteQuery(sql) {}
	virtual ~C_SQLiteInsert() {}

	inline void toTable(std::string name)	{ m_tname = name; }
	inline void add(std::string cname, std::string value) { m_columns.push_back(cname); m_values.push_back(value); }
	/////////////////////////////////////////////////////////////////////////
	////////////	exec
	inline void exec() {
		m_strQuery = "INSERT INTO " + m_tname + "(";
		FOR_VEC_I(it, m_columns, std::string)
		{
			m_strQuery += (*it) + ((it + 1 != m_columns.end()) ? ", " : ")");
		}

		m_strQuery += " VALUES(";

		FOR_VEC_I(it, m_values, std::string)
		{
			m_strQuery += (*it) + ((it + 1 != m_values.end()) ? ", " : ");");
		}
		//execution
		m_sql->exec(m_strQuery);
	}

	/////////////////////////////////////////////////////////////////////////
	////////////	execToStr
	inline virtual std::string execToStr() {
		m_strQuery = "INSERT INTO " + m_tname + "(";
		FOR_VEC_I(it, m_columns, std::string)
		{
			m_strQuery += (*it) + ((it + 1 != m_columns.end()) ? ", " : ")");
		}

		m_strQuery += " VALUES(";

		FOR_VEC_I(it, m_values, std::string)
		{
			m_strQuery += (*it) + ((it + 1 != m_values.end()) ? ", " : ");");
		}
		m_columns.clear(); m_values.clear();
		return m_strQuery;
	}
};


////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//			C_SQLiteMultiQuery
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
class C_SQLiteMultiQuery : public C_SQLiteQuery
{
private:
	int m_countQuery;
public:
	C_SQLiteMultiQuery(C_SQLite *sql) : C_SQLiteQuery(sql) { m_tname = "GROUP QUERY"; }
	virtual ~C_SQLiteMultiQuery() {}

	/////////////////////////////////////////////////////////////////////////
	////////////	add
	void add(C_SQLiteQuery *q) { m_strQuery += q->execToStr(); m_countQuery++; }
	/////////////////////////////////////////////////////////////////////////
	////////////	exec
	void exec() { 	
		//WR(m_strQuery);
		//execution
		m_sql->exec(m_strQuery, m_countQuery);
		m_countQuery = 0;
		m_strQuery = "";
	}
	/////////////////////////////////////////////////////////////////////////
	////////////	execToStr
	inline virtual std::string execToStr() {
		return m_strQuery;
	}
	/////////////////////////////////////////////////////////////////////////
	////////////	size
	inline int size() { return m_countQuery; }
};

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//			C_SQLiteSelect
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
class C_SQLiteSelect : public C_SQLiteQuery
{
private:
	std::string				 m_columns;
	std::string				 m_where;
public:
	C_SQLiteSelect(C_SQLite *sql) : C_SQLiteQuery(sql) { m_where = ""; }
	virtual ~C_SQLiteSelect() {}

	inline void setTable(std::string name)	{ m_tname = name; }
	inline void setColumns(std::string columns) { m_columns = columns; }
	inline void setWhere(std::string _where) { m_where = _where; }
	/////////////////////////////////////////////////////////////////////////
	////////////	exec
	inline void exec() {
		m_strQuery = "SELECT " + m_columns + " FROM " + m_tname + ((m_where == "") ? "" : " WHERE " + m_where) + "; ";
	}

	/////////////////////////////////////////////////////////////////////////
	////////////	execToStr
	inline virtual std::string execToStr() {
		m_strQuery = "SELECT " + m_columns + " FROM " + m_tname + ((m_where == "") ? "" : " WHERE " + m_where) + "; ";
		return m_strQuery;
	}
};

